<template>
  <!-- 基础富文本组件 -->
  <div class="baseEditorPage">
    <Toolbar
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="modeVal"
      class="toolBarBox"
    />
    <Editor
      :defaultConfig="editorConfig"
      :mode="modeVal"
      style="overflow-y: hidden"
      :style="`height:${getHight}`"
      v-model="valueHtml"
      @onCreated="handleCreated"
      @onChange="handleChange"
      @onDestroyed="handleDestroyed"
      @onFocus="handleFocus"
      @onBlur="handleBlur"
      @customAlert="customAlert"
      @customPaste="customPaste"
    />
  </div>
</template>
<script setup>
import "@wangeditor/editor/dist/css/style.css";
import { ElMessage } from "element-plus";
import { onBeforeUnmount, ref, shallowRef,watch } from "vue";
import store from "@/store";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";

const accessToken = store.state.user.accessToken;

const props = defineProps({
  getHight: {
    // 高度
    type: String,
    required: true,
    default: "400px",
  },
  getModeVal: {
    // 模式
    type: String,
    required: false,
    default: "default",
  },
  getHtmlContent: {
    // 内容
    type: String,
    required: false,
    default: "",
  },
  excludeArr: {
    // 需排除的menu的key值arr
    type: Array,
    required: false,
    default: [],
  },
});

// 编辑器实例，必须用 shallowRef，重要！
const editorRef = shallowRef();

// 显示内容的 HTML
const valueHtml = ref(null);

// 工具栏配置
const toolbarConfig = {
  // 配置需要显示的菜单组，如何排序、分组，如下：
  //   toolbarKeys: [
  //     "headerSelect",
  //     "|",
  //     "bold",
  //     "underline",
  //     "italic",
  //     "color",
  //     "bgColor",
  //     "|",
  //     "fontSize",
  //     "fontFamily",
  //     "lineHeight",
  //     "|",
  //     "bulletedList",
  //     "numberedList",
  //     "todo",
  //     "|",
  //     "emotion",
  //     "insertLink",
  //     "insertTable",
  //     "codeBlock",
  //     "divider",
  //   ],

  // 配置需要排除的菜单组，写菜单组 key 的值即可，如下:
  //   excludeKeys: [
  //     "headerSelect",
  //     "italic",
  //     "group-more-style",
  //   ],
  excludeKeys: props.excludeArr,
};

// 编辑器配置
const editorConfig = {
  placeholder: "请输入内容...",

  // 是否只读、不可编辑
  // readOnly: true,

  // 所有的菜单配置，都要在 MENU_CONF 属性下
  MENU_CONF: {
    // 配置上传图片，暂时不需要使用此功能
    uploadImage: {
      // 请求路径
      server: "/baseApi/bf-assets/file/upload/img",

      // 携带的数据
      meta: {
        token: accessToken,
      },
      // 将 meta 拼接到 url 参数中，默认 false
      metaWithUrl: true,

      // 后端接收的文件名称
      fieldName: "file",

      // 单个文件的最大体积限制，默认为 2M
      maxFileSize: 5 * 1024 * 1024, // 5M

      // 最多可上传几个文件，默认为 100
      maxNumberOfFiles: 10,

      // 上传的图片类型
      allowedFileTypes: ["image/*"],

      // 小于该值就插入 base64 格式（而不上传），默认为 0
      base64LimitSize: 1 * 1024 * 1024, // 1M

      // 自定义插入返回格式【后端返回的格式】
      customInsert(res, insertFn) {
        if (res.code !== 200) {
          ElMessage.error("上传文件失败");
          return;
        }

        // 从 res 中找到 url alt href ，然后插入图片
        insertFn(res.data.url, res.data.alt, res.data.href);
      },

      // 单个文件上传成功之后
      onSuccess(file, res) {
        if (res.code == 200) {
            return ElMessage.success(`${file.name} 上传成功`);
        } else {
            return ElMessage.warning(`${file.name} 上传出了点异常`);
        }
      },
      // 单个文件上传失败
      onFailed(file, res) {
        console.log(res);
        ElMessage.error(`${file.name} 上传失败，请重试`);
      },
      // 上传错误，或者触发 timeout 超时
      onError(file, err, res) {
        console.log(err, res);
        ElMessage.error(`${file.name} 上传出错`);
      },
    },
  },
};

// 模式 (默认/简洁)('default' / 'simple')
const modeVal = props.getModeVal;

// 编辑器创建完毕时的回调
const handleCreated = (editor) => {
    // console.log('editor.getAllMenuKeys()',editor.getAllMenuKeys())
  editorRef.value = editor; // 记录 editor 实例，重要！
  console.log("编辑器创建完成");
  // 查看菜单组的key值,需要时放出使用
  //   setTimeout(() => {
  //     const toolbarInfo = DomEditor.getToolbar(editor);
  //     const curToolbarConfig = toolbarInfo.getConfig().toolbarKeys;
  //     console.log("当前配置的菜单Key：", curToolbarConfig); // 当前菜单排序和分组
  //   }, 1000);
};

// 定义向父组件传值方法
const emits = defineEmits(["getEditorVal"]);
// 编辑器内容、选区变化时的回调。此处进行2s防抖处理
// editor - 编辑器实例
const handleChange = _.debounce(function (editor) {
  let editorVal = editor.getHtml();
  emits("getEditorVal", editorVal);
}, 2000);

// 编辑器 focus 时的回调
const handleFocus = (editor) => {
  console.log("focus", editor);
};

// 编辑器 blur 时的回调
const handleBlur = (editor) => {
  console.log("blur", editor);
};

// 自定义编辑器 alert
const customAlert = (info, type) => {
  ElMessage({
    type: type,
    message: info,
  });
};

// 自定义粘贴。可阻止编辑器的默认粘贴，实现自己的粘贴逻辑
/**
 * event    -  粘贴事件对象；
 * editor   -  富文本实例；
 * callback -  回掉。 注意，此处要用 vue 事件的返回值，不能用 return 。
 */
const customPaste = (editor, event, callback) => {
  // 自定义插入内容
  //   editor.insertText("xxx");

  // 返回 false ，阻止默认粘贴行为
  //   callback(false);

  // 返回 true ，允许默认的粘贴行为
  callback(true);
};

// 编辑器销毁时的回调
const handleDestroyed = (editor) => {
  console.log("编辑器已销毁");
};

// 组件销毁时，也及时销毁编辑器，重要！
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  // 销毁编辑器
  editor.destroy();
});

watch(()=>props.getHtmlContent,(value)=>{
  if(value){
    setTimeout(() => {
    const editor = editorRef.value;
    // 设置编辑器内容
    editor.dangerouslyInsertHtml(props.getHtmlContent);
    }, 600);
  }
});

// onMounted(() => {
//   setTimeout(() => {
//     const editor = editorRef.value;
//     console.log("获取编辑器实例：", editor);
//     console.log('props.getHtmlContent',props.getHtmlContent);
//     // 设置编辑器内容
//     editor.dangerouslyInsertHtml(props.getHtmlContent);
//   }, 600);
// });
</script>

<style lang="scss" scoped>
.baseEditorPage {
  border: 1px solid $title-sm-color;
  .toolBarBox {
    border-bottom: 1px solid $title-sm-color;
  }
  .editorBox {
    overflow-y: hidden;
  }
}
</style>
